function FileList() {
  var self=this;
  
  function getType(sFilename, sFiletype) {
    switch (sFiletype) {
      case TYPE_MAP:  return 'dir';
      case TYPE_FILE: return sFilename.substring(sFilename.lastIndexOf('.'), sFilename.length).replace(/\W/ig, '');
      default:        return '---';
    }
  }
  
  function getClass(sFilename, sFiletype) {
    switch (sFiletype) {
      case TYPE_MAP:  return 'dragitem map';
      case TYPE_FILE: return 'dragitem ' + getType(sFilename, sFiletype);
      default:        return 'unknown';
    }
  }
  
//  function stripDots(sPath) {
    
  
  function getLi(mData, bStandAlone) {
    var eLi = $('<li><span>'+mData['filename']+'</span></li>');
    for (var sProp in mData)
      eLi.attr(sProp, mData[sProp]);
    eLi.addClass(getClass(mData['filename'], mData['filetype']));
    eLi.draggable(mDrag);
    if (mData['filetype'] == TYPE_MAP)
      eLi.droppable(mDropItem);
    if (bStandAlone)
      return $('<ul>').append(eLi);
    return eLi;
  }
  
  this.getUl=function(aJson, sPath, bIncFiles) {
    var eUl = $('<ul>').attr('showspath', sPath);
    for (var i = 0; i < aJson.length; i++) {
      if (aJson[i].filename == '.' || aJson[i].filename == '..')
        continue;
      if (bIncFiles || aJson[i].filetype == TYPE_MAP)
        eUl.append(getLi(aJson[i], false));
    }
    if (bIncFiles)
      eUl.droppable(mDropView);
    return eUl;
  }
  
  this.getTbody=function(aJson, sPath) {
    var eTbody = $('<tbody>').attr('showspath', sPath.replace(/[^\/]+\/\.\./ig, '').replace(/\/$/ig, ''));
    for (var i = 0; i < aJson.length; i++) {
      if (aJson[i].filename == '.')
        continue;
      eTbody.append(
        $('<tr>').append($('<td>').append(getLi(aJson[i], true)))
                 .append($('<td>' + getType(aJson[i].filename, aJson[i].filetype) + '</td>'))
                 .append($('<td>' + aJson[i].filesize + '</td>'))
                 .append($('<td>' + aJson[i].modified + '</td>'))
      );
    }
//    eTbody.droppable(mDropView);
    return eTbody;
  }
}
